﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.IO;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace FTUninstaller
{
    public partial class QTPUninstaller
    {
        RegistryItemScan KeyScannerIID = (string Key, QTPUninstaller scan) =>
            {
                RegistryKey typeLib;
                typeLib = Registry.ClassesRoot.OpenSubKey(scan.PathIID + Key + "\\TypeLib");
                if (typeLib == null) return false;
                string sTypeLib = (string)typeLib.GetValue("");
                if (scan.MatchedTypeLibs.Contains(sTypeLib) && !scan.MatchedIIDs.Contains(Key))
                    scan.MatchedIIDs.Add(Key);
                typeLib.Close();
                return false;
            };

        RegistryItemScan KeyScannerInstalledComponent = (string Key, QTPUninstaller scan) =>
        {
            RegistryKey installKey;
            installKey = Registry.LocalMachine.OpenSubKey(scan.PathInstall + Key + "\\Products");
            if (installKey == null) return false;
            string[] arrSubKeys = installKey.GetSubKeyNames();
            arrSubKeys = arrSubKeys.Where(subKey =>
                {
                    RegistryKey displayNameKey;
                    displayNameKey = Registry.LocalMachine.OpenSubKey(scan.PathInstall + Key + "\\Products\\" + subKey + "\\InstallProperties");
                    if (displayNameKey == null) return false;
                    string sDisplayKey = (string)displayNameKey.GetValue("DisplayName");
                    if (sDisplayKey == "") return false;
                    if (scan.IsQTPRelated(sDisplayKey))
                        scan.MatchedInstallerComponents.Add(scan.PathInstall + Key + "\\Products\\" + subKey);
                    displayNameKey.Close();
                    return false;
                }).ToArray();
            //scan.MatchedInstallerComponents.AddRange(arrSubKeys);
            return false;
        };

        RegistryItemScan KeyScannerUninstall = (string Key, QTPUninstaller scan) =>
        {
            RegistryKey product;
            product = Registry.ClassesRoot.OpenSubKey(scan.PathUninstall + Key);
            if (product == null) return false;

            string sDisplayName = product.GetValue("").ToString().ToLower();
            if (scan.IsQTPRelated(sDisplayName))
                return true;
            //if (sDisplayName.Contains("quicktest") && sDisplayName.Contains("quality") && sDisplayName.Contains("center"))
            //    return true;
            //if (sDisplayName.Contains("hp") && sDisplayName.Contains("run") && sDisplayName.Contains("result"))
            //    return true;

            return false;
        };

        RegistryItemScan KeyScannerProgID = (string Key, QTPUninstaller scan) =>
        {
            string sKey = Key.ToLower();
            if (sKey.Contains("merucry.") ||
                sKey.Contains("mercury.") ||
                sKey.Contains("quicktest") ||
                sKey.Contains("micacxtable") ||
                sKey.Contains("aqt") ||
                sKey.Contains("bb flashBack player.document") ||
                sKey.Contains("rainbow.sentinellm"))
            {
                //scan.MatchedProgIDs.Add(Key);
                RegistryKey oRegKey;
                oRegKey = Registry.ClassesRoot.OpenSubKey(Key + "\\CLSID");

                if (oRegKey != null)
                {
                    string CLSID = (string)oRegKey.GetValue("");
                    if (CLSID != "" && !scan.MatchedCLSIDs.Contains(CLSID))
                        scan.MatchedCLSIDs.Add(CLSID);
                    oRegKey.Close();
                }
                return true;
            }
            return false;
        };

        RegistryItemScan KeyScannerTypeLib = (string Key, QTPUninstaller scan) =>
        {
            if (scan.MatchedTypeLibs.Contains(Key)) return false;
            RegistryKey oTypeLib = Registry.ClassesRoot.OpenSubKey(scan.PathTypeLib + Key);
            if (oTypeLib == null) return false;
            string[] childKeys = oTypeLib.GetSubKeyNames();
            foreach (string item in childKeys)
            {
                RegistryKey oDLLFile = oTypeLib.OpenSubKey(item + "\\0\\win32");
                if (oDLLFile == null) continue;
                string sFileName = (string)oDLLFile.GetValue("");
                if (sFileName == null || sFileName == "") continue;
                if (scan.IsQTPDll(sFileName))
                    return true;
            }

            return false;
        };

        RegistryItemScan KeyScannerAppID = (string Key, QTPUninstaller scan) =>
        {
            //if AppID already exists then no need to re-process it
            if (scan.MatchedAppIDs.Contains(Key)) return false;

            RegistryKey oAppIDDesc = Registry.ClassesRoot.OpenSubKey(scan.PathAppID + Key);

            //if for any case we cannot open the key then no need to process it
            if (oAppIDDesc == null) return false;

            string sAppDesc = (string)oAppIDDesc.GetValue("");

            oAppIDDesc.Close();

            if (sAppDesc == null) return false;

            if (scan.IsQTPRelated(sAppDesc))
                return true;
            //if (sAppDesc.Contains("quicktest") && sAppDesc.Contains("quality") && sAppDesc.Contains("center"))
            //    return true;
            //if (sAppDesc.Contains("hp") && sAppDesc.Contains("run") && sAppDesc.Contains("result"))
            //    return true;
            return false;
        };

        RegistryItemScan KeyScannerCLSID = (string Key, QTPUninstaller scan) =>
        {
            RegistryKey oRegKey = null;
            oRegKey = Registry.ClassesRoot.OpenSubKey(scan.PathCLSID + Key + "\\InprocServer32");

            //if it's not a DLL then may be it is a COM EXE
            if (oRegKey == null) oRegKey = Registry.ClassesRoot.OpenSubKey(scan.PathCLSID + Key + "\\LocalServer32");

            //if nothing no need to process
            if (oRegKey == null) return false;

            string strDLLFile = (string)oRegKey.GetValue("");

            if (strDLLFile == null) return false;

            //this is a .NET DLL which is not installed on GAC
            //we won't touch GAC in this
            if (strDLLFile.Contains("mscoree.dll"))
                strDLLFile = (string)oRegKey.GetValue("codebase");

            if (strDLLFile == null) return false;

            //register the TypeLib related to this DLL if any
            RegistryKey typeLib = Registry.ClassesRoot.OpenSubKey(scan.PathCLSID + Key + "\\TypeLib");

            if (oRegKey != null) oRegKey.Close();

            if (scan.IsQTPDll(strDLLFile))
            {
                if (typeLib != null)
                {
                    string sTypeLib;
                    sTypeLib = (string)typeLib.GetValue("");
                    if (sTypeLib != null && sTypeLib != "" && !scan.MatchedTypeLibs.Contains(sTypeLib))
                        scan.MatchedTypeLibs.Add(sTypeLib);
                    typeLib.Close();
                }
                return true;
            }
            return false;
        };

        public IEnumerable<string> PerformScan(string[] keys, RegistryItemScan scanner)
        {
            UpdateProgressEventArgs e = new UpdateProgressEventArgs(0, keys.Length, "Performing registry scan\n please wait this may take few mins");
            int value = 0;

            List<string> keysfound = new List<string>();
            foreach (string key in keys)
            {
                e.Value = ++value;
                OnUpdateProgress(e);

                if (scanner(key, this))
                    keysfound.Add(key);
            }
            return keysfound;
        }

    }
}
